import cgi
import os
import urllib
import logging
import math
import time, datetime
import string

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from google.appengine.ext.db import Timeout
from google.appengine.ext.webapp import template
#from google.appengine.api import memcache
from google.appengine.api import urlfetch
from google.appengine.api.urlfetch import DownloadError, InvalidURLError
from xml.dom.minidom import parse, parseString

# Set the debug level
_DEBUG = True
_GAE_DataStore_Fetch_lim=1000/2
_GAE_DataStore_Put_lim=500/2
_GAE_DataStore_Delete_lim=500/2

def getText(nodelist):
  #print nodelist.nodeType
  rc = ""
  for node in nodelist:
    if node.nodeType == node.TEXT_NODE:
      rc = rc + node.data
    return rc
  
def simple_Datetime_Parse(datetime_str):
  tmp_time = time.strptime(datetime_str, "%Y-%m-%d %H:%M:%S")
  dt_year = tmp_time.tm_year
  dt_month = tmp_time.tm_mon
  dt_date = tmp_time.tm_mday
  dt_hour = tmp_time.tm_hour
  dt_min = tmp_time.tm_min
  dt_sec = tmp_time.tm_sec
  
  return datetime.datetime(dt_year,dt_month,dt_date,dt_hour,dt_min,dt_sec,0)

def Landmarks_Sort_by_distance(Landmarks):
  # gnomeSort Algorithm: http://en.wikipedia.org/wiki/Gnome_sort
  i = 1
  j = 2
  size = len(Landmarks)
  while i < size:
    if Landmarks[i-1].distance <= Landmarks[i].distance: # for descending sort, reverse the comparison to >=
      i = j
      j = j + 1 
    else:
      # swap a[i-1] and a[i]
      landmark = Landmarks[i-1]
      Landmarks[i-1] = Landmarks[i]
      Landmarks[i] = landmark
      i = i - 1
      if i == 0:
        i = 1
  return Landmarks

class Landmark(db.Model):
  name = db.StringProperty()
  lng = db.FloatProperty()
  lat = db.FloatProperty()
  lng_zone_id = db.IntegerProperty()
  description = db.StringProperty()
  def __CMP__(self,other):
    return self.distance-other.distance

##class Landmark_sortable(Landmark):
##  Distance = db.FloatProperty()
##  def __cmp__(self, other):
##    return self.Distance-other.Distance
  
class PathInfo(db.Model):
  Title = db.StringProperty()
  StartDatetime = db.DateTimeProperty()
  EndDatetime = db.DateTimeProperty()
  Source = db.StringProperty()
  Destination = db.StringProperty()
  Distance = db.FloatProperty()
  Duration = db.IntegerProperty()
  MaxVelocity = db.FloatProperty()
  Description = db.StringProperty()
  KMLurl = db.LinkProperty()
  TotalPlacemarkNum = db.IntegerProperty()
  #StorePlacemarkNum = db.IntegerProperty()
  
class GeoInfo(db.Model):
  idx = db.IntegerProperty()
  lng = db.FloatProperty()
  lat = db.FloatProperty()
  datetime = db.DateTimeProperty()
  height = db.FloatProperty()
  distance = db.FloatProperty()
  velocity = db.FloatProperty()
  description = db.StringProperty()
  ref = db.ReferenceProperty(PathInfo)

class ErrLog(db.Model):
  ErrorType = db.StringProperty()
  Content = db.StringProperty(multiline=True)
  DateTime = db.DateTimeProperty(auto_now_add=True)
  
class GeoUser(db.Model):
  user = db.UserProperty()
  join_date = db.DateTimeProperty(auto_now_add=True)
  accepte_date = db.DateTimeProperty()
  picture = db.LinkProperty()
  city = db.StringProperty()
  website = db.LinkProperty()
  
class Greeting(db.Model):
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

class BaseRequestHandler(webapp.RequestHandler):
  """Base request handler extends webapp.Request handler

     It defines the generate method, which renders a Django template
     in response to a web request
  """

  def generate(self, template_name, template_values={}):
    """Generate takes renders and HTML template along with values
       passed to that template

       Args:
         template_name: A string that represents the name of the HTML template
         template_values: A dictionary that associates objects with a string
           assigned to that object to call in the HTML template.  The defualt
           is an empty dictionary.
    """
    # We check if there is a current user and generate a login or logout URL
    user = users.get_current_user()

    if user:
      log_in_out_url = users.create_logout_url('/')
    else:
      log_in_out_url = users.create_login_url(self.request.path)

    # We'll display the user name if available and the URL on all pages
    values = {'user': user, 'log_in_out_url': log_in_out_url}
    values.update(template_values)

    # Construct the path to the template
    directory = os.path.dirname(__file__)
    path = os.path.join(directory, 'templates', template_name)

    # Respond to the request by rendering the template
    self.response.out.write(template.render(path, values, debug=_DEBUG))
    
class MainRequestHandler(BaseRequestHandler):
  def get(self):
    if users.get_current_user():
      url = users.create_logout_url(self.request.uri)
      url_linktext = 'Logout'
    else:
      url = users.create_login_url(self.request.uri)
      url_linktext = 'Login'

    template_values = {
      'url': url,
      'url_linktext': url_linktext,
      }

    self.generate('geoxml-kml.html', template_values)

class MaintainaceHandler(BaseRequestHandler):
  def TimeoutError_Handler(self,all_wild_placemark_num,StartDatetime):
    self.response.out.write('Error: Timeout: Maintainace: Wild?' + str(all_wild_placemark_num)+
                            'StartDatetime?'+str(StartDatetime))
    
  def GeoInfo_Maintainace(self,StartDatetime):
    all_wild_placemark_num = 0
    geoPositions_query = db.Query(GeoInfo)
    geoPositions_query.order('datetime')
    geoPositions_query.filter('datetime >=',StartDatetime)
    placemarks = geoPositions_query.fetch(_GAE_DataStore_Delete_lim)

    #debug_str = 'debug:'
    while len(placemarks):
      for placemark in placemarks:
        try:
          pathinfo = placemark.ref
        except:
          pathinfo = None
          
        if pathinfo:
          geoPositions_query = db.Query(GeoInfo)
          geoPositions_query.order('-datetime')
          geoPositions_query.filter('ref =',pathinfo.key())
          placemark2 = geoPositions_query.fetch(1)[0]
          StartDatetime = placemark2.datetime
          #debug_str+='v'
          break
        else:
          try:
            db.delete(placemark)
            all_wild_placemark_num += 1
            #debug_str+='x'
            StartDatetime = placemark.datetime
          except Timeout:
            self.TimeoutError_Handler(all_wild_placemark_num,StartDatetime)
            return
          if False:
            while True:
              geoPositions_query = db.Query(GeoInfo)
              geoPositions_query.order('datetime')
              geoPositions_query.filter('ref =',last_ref)
              placemarks = geoPositions_query.fetch(_GAE_DataStore_Delete_lim)
              wild_placemark_num =len(placemarks)
              if wild_placemark_num:
                try:
                  db.delete(placemarks)
                  all_wild_placemark_num = all_wild_placemark_num + wild_placemark_num
                  StartDatetime = placemarks[-1].datetime
                except Timeout:
                  self.TimeoutError_Handler(all_wild_placemark_num,StartDatetime)
                  return
              else:
                break
      geoPositions_query = db.Query(GeoInfo)
      geoPositions_query.order('datetime')
      geoPositions_query.filter('datetime >',StartDatetime)
      placemarks = geoPositions_query.fetch(_GAE_DataStore_Delete_lim)
    
    self.response.out.write('Success: Maintainace: GeoInfo: Wild?' + str(all_wild_placemark_num)+
                            '&StartDatetime?'+str(StartDatetime))
      
  def get(self):
    if users.get_current_user():
      current_user = users.get_current_user()
      User_query = db.Query(GeoUser)
      User_query.filter('user =', current_user)
      User_set = User_query.fetch(_GAE_DataStore_Fetch_lim)
      if len(User_set)==1:
        arguments = self.request.arguments()
        for argument in arguments:
          if argument == 'StartDatetime':
            StartDatetime=simple_Datetime_Parse(self.request.get(argument))
            self.GeoInfo_Maintainace(StartDatetime)
          else:
            self.response.out.write('Error: Unknown argument: Maintainace:'+argument)
      else:
        self.response.out.write('Error: Autentication: Maintainace: Not Admin')
    else:
      self.response.out.write('Error: Autentication: Maintainace: Not Logged in')

class StaticRequestHandler(BaseRequestHandler):
  def get(self):
    self.generate('scroll_toggle_local.html',{})

class delKMLHandler(BaseRequestHandler):
  def TimeoutError_Handler(self):
    self.response.out.write('Error: Timeout: KML deletion Failed')
    
  def get(self):
    User_query = db.Query(GeoUser)
    User_set = User_query.fetch(_GAE_DataStore_Fetch_lim)
    if len(User_set)==0:
      if users.get_current_user():
        admin = GeoUser(user = users.get_current_user())
        admin.put()
        
    if users.get_current_user():
      current_user = users.get_current_user()
      User_query = db.Query(GeoUser)
      User_query.filter('user =', current_user)
      User_set = User_query.fetch(_GAE_DataStore_Fetch_lim)
      if len(User_set)==1:
        arguments = self.request.arguments()
        for argument in arguments:
          if argument == 'StartDatetime':
            StartDatetime=simple_Datetime_Parse(self.request.get(argument))
          elif argument == 'EndDatetime':
            EndDatetime=simple_Datetime_Parse(self.request.get(argument))

        Path_query = db.Query(PathInfo)
        Path_query.filter('StartDatetime =', StartDatetime).filter('EndDatetime =', EndDatetime)
        Path_set = Path_query.fetch(_GAE_DataStore_Fetch_lim)
        if len(Path_set):
          pathinfo = Path_set[0]
          ref_key = pathinfo.key()
          
          while True:
            geoPositions_query = db.Query(GeoInfo)
            geoPositions_query.filter('ref =',ref_key)
            placemarks = geoPositions_query.fetch(_GAE_DataStore_Delete_lim)
            if len(placemarks):
              try:
                db.delete(placemarks)
              except Timeout:
                self.TimeoutError_Handler()
                return
            else:
              break
          pathinfo.delete()
          self.response.out.write('Success: KML deleted')
        else:
          self.response.out.write('Error: db.pathinfo: Not Found')       
      else:
        self.response.out.write('Error: Autentication: Not Admin')
    else:
      self.response.out.write('Error: Autentication: Not Logged in')
    
class setKMLRequestHandler(BaseRequestHandler):
  def Landmark_Parse(self,xmldoc):
    landmark = Landmark()
    landmark.name = getText(xmldoc.getElementsByTagName("Name")[0].childNodes)

    lat = xmldoc.getElementsByTagName("lat")
    if len(lat):
      landmark.lat = float(getText(lat[0].childNodes))
      lng = xmldoc.getElementsByTagName("lng")
      landmark.lng = float(getText(lng[0].childNodes))
      landmark.lng_zone_id = int(round(landmark.lng*60))

    description = xmldoc.getElementsByTagName("Description")
    if len(description):
      landmark.description = getText(description[0].childNodes)

    if len(lat) or len(description):
      Landmark_query = db.Query(Landmark)
      Landmark_query.filter('name =', landmark.name)
      Landmark_set = Landmark_query.fetch(_GAE_DataStore_Fetch_lim)
      if len(Landmark_set):
        Landmark_set[0].lat = landmark.lat
        Landmark_set[0].lng = landmark.lng
        Landmark_set[0].lng_zone_id = landmark.lng_zone_id
        Landmark_set[0].description = landmark.description
        Landmark_set[0].put()
      else:
        landmark.put()

    return landmark
        
  def post(self):
    content = self.request.get('content')
    xmldoc = parseString(content)
    #self.response.out.write(content)
    StartDatetime_Node = xmldoc.getElementsByTagName("StartDatetime")[0]
    StartDatetime_str = getText(StartDatetime_Node.childNodes)
    StartDatetime = simple_Datetime_Parse(StartDatetime_str)
    
    EndDatetime_Node = xmldoc.getElementsByTagName("EndDatetime")[0]
    EndDatetime_str = getText(EndDatetime_Node.childNodes)
    EndDatetime = simple_Datetime_Parse(EndDatetime_str)
    
    Path_query = db.Query(PathInfo)
    Path_query.filter('StartDatetime =', StartDatetime).filter('EndDatetime =', EndDatetime)
    Path_set = Path_query.fetch(_GAE_DataStore_Fetch_lim)
    if len(Path_set):
      pathinfo = Path_set[0]

      SourceNodes = xmldoc.getElementsByTagName("Source")
      if len(SourceNodes):
        Source = self.Landmark_Parse(SourceNodes[0]);
        pathinfo.Source = Source.name

      DestinationNodes = xmldoc.getElementsByTagName("Destination")
      if len(DestinationNodes):
        Destination = self.Landmark_Parse(DestinationNodes[0])
        pathinfo.Destination = Destination.name

      PathNodes = xmldoc.getElementsByTagName("Path")
      Description_Nodes = PathNodes[0].getElementsByTagName("Description")
      if len(Description_Nodes):
        pathinfo.Description = getText(Description_Nodes[0].childNodes)
        
      pathinfo.put()
      
      self.response.out.write('KML updated'+str(pathinfo.Duration))
    else:
      self.response.out.write('KML not found')

class LANDMARKinfoRequestHandler(BaseRequestHandler):
  def get(self):
    arguments = self.request.arguments()
    for argument in arguments:
      if argument == 'lat':
        lat=float(self.request.get(argument))
      elif argument == 'lng':
        lng=float(self.request.get(argument))
      elif argument == 'rad':
        rad=float(self.request.get(argument))
        if rad<0:
          rad=-rad
        if rad>0.1:
          rad=0.1

    lng_zone_id_lower = int(round((lng-rad)*60))
    lng_zone_id_upper = int(round((lng+rad)*60))# bug!!! dangerous when world wrap-arround
    lng_zone_num = (lng_zone_id_upper-lng_zone_id_lower+1)
    lng_zone_id = lng_zone_id_lower
    
    Landmark_Fetch_lim = _GAE_DataStore_Fetch_lim#20#
    Landmark_Fetch_Num = Landmark_Fetch_lim/2/lng_zone_num
    Landmark_set = []
    Debug_str = ''
    while lng_zone_id <= lng_zone_id_upper:
##      Landmark_query = db.Query(Landmark)
##      Landmark_query.order('-lat')
##      #Landmark_query.filter('lat <=', lat)
##      Landmark_query.filter('lng_zone_id =', lng_zone_id)
##      Landmark_set_tmp = Landmark_query.fetch(Landmark_Fetch_Num)
##      Landmark_set = Landmark_set + Landmark_set_tmp
##      Debug_str = Debug_str + ' >>>> lat <='+ str(lat)+ 'lng_zone_id='+str(lng_zone_id)+'Landmark_Fetch_Num'+str(Landmark_Fetch_Num)
##      for landmark in Landmark_set_tmp:
##        Debug_str = Debug_str + '|||'+landmark.name

      Landmark_query = db.Query(Landmark)
      #Landmark_query.order('lat')
      #Landmark_query.filter('lat >', lat)
      Landmark_query.filter('lng_zone_id =', lng_zone_id)
      Landmark_set_tmp = Landmark_query.fetch(Landmark_Fetch_Num)
      Landmark_set = Landmark_set + Landmark_set_tmp
      Debug_str = Debug_str + ' >>>> lat >'+ str(lat)+ 'lng_zone_id='+str(lng_zone_id)+'Landmark_Fetch_Num'+str(Landmark_Fetch_Num)
      for landmark in Landmark_set_tmp:
        Debug_str = Debug_str + '|||'+landmark.name

      lng_zone_id = lng_zone_id + 1
##    Landmark_query = db.Query(Landmark)
##    Landmark_query.order('lat')
##    #Landmark_query.filter('lat >', lat-rad)
##    #Landmark_query.filter('lng_zone_id =', lng_zone_id)
##    Landmark_set = Landmark_query.fetch(Landmark_Fetch_Num)
    for landmark in Landmark_set:
      landmark.distance = ((lat - landmark.lat)**2+(lng - landmark.lng)**2)**0.5*math.pi/180*6378137
    #Landmark_set.sort(None,Landmark_CMP_by_distance,False)
    #Landmark_set.sort()

    Landmark_set = Landmarks_Sort_by_distance(Landmark_set)
    Debug_str = Debug_str+'All: lng='+str(lng)+';lat='+str(lat)+';rad='+str(rad)+';L='+str(lng_zone_id_lower)+';U='+str(lng_zone_id_upper)+';Landmark_Fetch_Num='+str(Landmark_Fetch_Num)
    template_values = {
      'landmarks': Landmark_set,
      'Debug_str': Debug_str
      }
    
    self.generate('Landmarks.kml', template_values)
    
class PATHinfoRequestHandler(BaseRequestHandler):
  def DownloadError_Handler(self,url):
    Debug_str='Error: Download Error:'
    Path_set=[]
    template_values = {
      'Path_set': Path_set,
      'Path_Col_URL': url,
      'Debug_str': Debug_str
      }
    # Webob over quotes the request URI, so we have to unquote twice
    self.generate('PathInfos.xml', template_values);
    
  def InvalidURLError_Handler(self,url):
    Debug_str='Error: Invalid URL:'
    Path_set=[]
    template_values = {
      'Path_set': Path_set,
      'Path_Col_URL': url,
      'Debug_str': Debug_str
      }
    # Webob over quotes the request URI, so we have to unquote twice
    self.generate('PathInfos.xml', template_values);
    
  def parseString_to_KMLurl(self,Urlstr):
    KMLurls = Urlstr.split('.kml')
    idx = 0
    while idx < len(KMLurls):
      str_idx = KMLurls[idx].rfind('http://')
      if str_idx == -1:
        del KMLurls[idx]
      else:
        KMLurls[idx]=KMLurls[idx][str_idx:len(KMLurls[idx])] + '.kml'
        idx = idx + 1
    if len(KMLurls)>0:
      if Urlstr.endswith('.kml') == False:
        del KMLurls[-1]
    return KMLurls
        
  def get(self):
    #content = self.request.get('content')
    #url = content
    arguments = self.request.arguments()
    for argument in arguments:
      if argument == 'Path_Col_URL':
        url=self.request.get(argument)
      elif argument == 'Filter':
        isFilterOn=(self.request.get(argument)=='On')
    
    if len(url)>0:
      # check if is valid url
      result = urlfetch.fetch(url) #href
      try:
        result = urlfetch.fetch(url)
      except DownloadError:
        self.DownloadError_Handler(url)
        return
      except InvalidURLError:
        self.InvalidURLError_Handler(url)
        return

      KMLurls_str = result.content
    else:
      KMLurls_str = url
    
    KMLurls = self.parseString_to_KMLurl(KMLurls_str)
    #links = xmldoc.getElementsByTagName("a")

    if isFilterOn:
      Path_set=[];
      for KMLurl in KMLurls:
        Path_query = db.Query(PathInfo)
        Path_query.filter('KMLurl =',KMLurl)
        if Path_query.count(1)==0:
          Path_set.append(PathInfo(KMLurl=KMLurl))
    else:
      Path_query = db.Query(PathInfo)
      Path_query.order('StartDatetime')
      Path_set = Path_query.fetch(_GAE_DataStore_Fetch_lim)
      for KMLurl in KMLurls:
        Path_set.append(PathInfo(KMLurl=KMLurl))
      
    Debug_str = 'Success: ???'
    template_values = {
      'Path_set': Path_set,
      'Path_Col_URL': url,
      'Debug_str': Debug_str
      }
    # Webob over quotes the request URI, so we have to unquote twice
    self.generate('PathInfos.xml', template_values);
  
class KMLinfoRequestHandler(BaseRequestHandler):
  def Datetime_Parse(self,datetime_str):
##    time_format = "%H:%M:%S"
##    #Month_Str_Const = 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'
##    Month_Str_List = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
##    datetime_strs = datetime_str.split(' ')
##    dt_year = string.atoi(datetime_strs[4])
##    dt_month = Month_Str_List.index(datetime_strs[1])+1
##    dt_date = string.atoi(datetime_strs[2])
##    time_strs = datetime_str[3].split(':')
##    #print datetime_strs[0]+datetime_strs[1]+datetime_strs[2]+datetime_strs[3]
##    timestring=datetime_strs[3]
##    tmp_time = time.strptime(timestring, time_format)

    tmp_time = time.strptime(datetime_str[1:len(datetime_str)-1], "%a %b %d %H:%M:%S %Y")
    dt_year = tmp_time.tm_year
    dt_month = tmp_time.tm_mon
    dt_date = tmp_time.tm_mday
    #print time_strs
    dt_hour = tmp_time.tm_hour
    #string.atoi(time_strs[0])
    dt_min = tmp_time.tm_min
    dt_sec = tmp_time.tm_sec
    
    return datetime.datetime(dt_year,dt_month,dt_date,dt_hour,dt_min,dt_sec,0)

  def Placemark_Parse(self,placemark,geoPosition_last,GPindex):
    datetimes = placemark.getElementsByTagName("name")[0]
    datetime_str = getText(datetimes.childNodes)
    datetime_val=self.Datetime_Parse(datetime_str)
    
    coordinates = placemark.getElementsByTagName("coordinates")[0]
    latitudes = getText(coordinates.childNodes)
    latitude_values = latitudes.split(',')
    lng = float(latitude_values[0])
    lat = float(latitude_values[1])
    height = float(latitude_values[2])
    if GPindex == 0:
      velocity = 0.0
      distance = 0.0
    else:
      distance = ((lat - geoPosition_last.lat)**2+(lng - geoPosition_last.lng)**2)**0.5*math.pi/180*6378137
      
      time_diff = datetime_val - geoPosition_last.datetime
      if time_diff.seconds == 0:
        velocity = distance*3.6 / 1
      else:
        velocity = distance*3.6 / time_diff.seconds
        
    return GeoInfo(lat=lat, lng=lng, height=height, distance=distance, velocity=velocity, datetime=datetime_val,idx=GPindex)

  def DownloadError_Handler(self,url):
    Debug_str='Error: Download Error: KMLurl:'
    geoPositions=[]
    template_values = {
      'Placemarks': geoPositions,
      'KML_url': url,
      'Debug_str': Debug_str
      }
    
    errlog = ErrLog(ErrorType = Debug_str, Content = url)
    errlog.put()
    self.generate('GeoInfos.xml', template_values);
    
  def InvalidURLError_Handler(self,url):
    Debug_str='Error: Invalid URL: KMLurl:'
    geoPositions=[]
    template_values = {
      'Placemarks': geoPositions,
      'KML_url': url,
      'Debug_str': Debug_str
      }
    
    errlog = ErrLog(ErrorType = Debug_str, Content = url)
    errlog.put()
    self.generate('GeoInfos.xml', template_values);
    
  def post(self):
    greeting = Greeting()

    if users.get_current_user():
      greeting.author = users.get_current_user()

    greeting.content = self.request.get('content')
    greeting.put()
    
    url = greeting.content
    #result = urlfetch.fetch(url)

    try:
      result = urlfetch.fetch(url)
    except DownloadError:
      self.DownloadError_Handler(url)
      return
    except InvalidURLError:
      self.InvalidURLError_Handler(url)
      return

    # if result.status_code == 200:
    xmldoc = parseString(result.content)
    pfolder = xmldoc.getElementsByTagName("Folder")[0]

    GPindex = 0
    fetch_time=0
    
    geoPositions=[]
    placemarks = pfolder.getElementsByTagName("Placemark")
    geoPosition_last = GeoInfo()
    geoPosition_end = self.Placemark_Parse(placemarks[-1],geoPosition_last,GPindex)
    geoPosition = self.Placemark_Parse(placemarks[0],geoPosition_last,GPindex)
    
    Path_query = db.Query(PathInfo)
    Path_query.filter('StartDatetime =', geoPosition.datetime).filter('EndDatetime =', geoPosition_end.datetime)
    Path_set = Path_query.fetch(_GAE_DataStore_Fetch_lim)
    if len(Path_set):
      pathinfo = Path_set[0]
      ref_key = pathinfo.key()
      Debug_str = 'Success: Existing Path'
      
      while _GAE_DataStore_Fetch_lim*fetch_time < len(placemarks):
        geoPositions_query = db.Query(GeoInfo)
        geoPositions_query.filter('ref =',ref_key)
        geoPositions_query.order('idx')
        geoPositions_query.filter('idx >=', _GAE_DataStore_Fetch_lim*fetch_time).filter('idx <', _GAE_DataStore_Fetch_lim*(fetch_time+1))
        geoPositions = geoPositions + geoPositions_query.fetch(_GAE_DataStore_Fetch_lim)
        fetch_time = fetch_time + 1
    else:
      Debug_str = 'Success: New Path'
      time_diff = geoPosition_end.datetime - geoPosition.datetime
      pathinfo = PathInfo(StartDatetime = geoPosition.datetime,EndDatetime=geoPosition_end.datetime,Duration=time_diff.seconds,KMLurl=url,Distance=-0.1)
      ref_key = pathinfo.put()

    if len(geoPositions) < len(placemarks):
      GPindex = 0
      geoPos_idx = 0
      geoPositions_len_orig = len(geoPositions)
      put_time=0
      geoPositions_integrity = True
      Distance = 0.0
      MaxVelocity = -0.1
      
      geoPositions_toPut=[]
      while GPindex < len(placemarks):
        Parse_New = True
        if geoPos_idx < geoPositions_len_orig:
          if geoPositions[geoPos_idx].idx==GPindex:
            geoPosition_last = geoPositions[geoPos_idx]
            
            geoPos_idx = geoPos_idx + 1
            Parse_New = False
        if Parse_New:
          geoPosition = self.Placemark_Parse(placemarks[GPindex],geoPosition_last,GPindex)
          geoPosition.ref = ref_key
          geoPositions.append(geoPosition)
          geoPosition_last = geoPosition

          geoPositions_toPut.append(geoPosition)
          if len(geoPositions_toPut)==_GAE_DataStore_Put_lim:
            try: 
              db.put(geoPositions_toPut)
              geoPositions_toPut=[]
              put_time=put_time+1
            except Timeout:
              geoPositions_integrity = False
              raise Exception(put_time, 'eggs')

        Distance = Distance + geoPosition_last.distance
        if MaxVelocity < geoPosition_last.velocity:
          MaxVelocity = geoPosition_last.velocity
        GPindex = GPindex + 1
      
      if len(geoPositions_toPut)>0:
        try:
          db.put(geoPositions_toPut)
        except Timeout:
          geoPositions_integrity = False
          raise Exception(put_time, 'eggs')

      if geoPositions_integrity == True:
        pathinfo.Distance = Distance
        pathinfo.MaxVelocity = MaxVelocity
        pathinfo.put()
        
    else:
      if (pathinfo.Distance < 0) or (pathinfo.Distance is None) or (pathinfo.MaxVelocity<0):
        MaxVelocity = -0.1
        Distance = 0.0
        for geoPosition in geoPositions:
          Distance = Distance + geoPosition.distance
          if MaxVelocity < geoPosition.velocity:
            MaxVelocity = geoPosition.velocity
        pathinfo.Distance = Distance
        pathinfo.MaxVelocity = MaxVelocity
        pathinfo.put()
          
    #geoPositions_query = db.Query(GeoInfo)
    #
    
    template_values = {
      'Path_set': [pathinfo],
      'Placemarks': geoPositions,
      'KML_url': url,
      'Debug_str': Debug_str
      }
    """When requesting the URL, we find out that user's WikiUser information.
       We also retrieve articles written by the user
    """
    # Webob over quotes the request URI, so we have to unquote twice
    self.generate('GeoInfos.xml', template_values);

    # remove redundent KML record
    # do this clean job after user interaction is done
    while len(Path_set)>1:
      pathinfo = Path_set.pop()
      ref_key = pathinfo.key()
      while _GAE_DataStore_Fetch_lim*fetch_time < len(placemarks):
        geoPositions_query = db.Query(GeoInfo)
        geoPositions_query.filter('ref =',ref_key)
        geoPositions_query.filter('idx >=', _GAE_DataStore_Fetch_lim*fetch_time).filter('idx <', _GAE_DataStore_Fetch_lim*(fetch_time+1))
        geoPositions_query.fetch(_GAE_DataStore_Fetch_lim).delete()
        fetch_time = fetch_time + 1
      
      pathinfo.delete()
                                                
application = webapp.WSGIApplication(
                                     [('/', MainRequestHandler),
                                      ('/setKMLinfo', setKMLRequestHandler),
                                      ('/delKMLinfo', delKMLHandler),
                                      ('/getKMLinfo', KMLinfoRequestHandler),
                                      ('/getPATHinfo', PATHinfoRequestHandler),
                                      ('/getLANDMARKinfo', LANDMARKinfoRequestHandler),
                                      ('/maintainace', MaintainaceHandler),
                                      ('/static-debug', StaticRequestHandler)],
                                     debug=True)

def real_main():
  run_wsgi_app(application)

def profile_main():
 # This is the main function for profiling 
 # We've renamed our original main() above to real_main()
 import cProfile, pstats, StringIO
 prof = cProfile.Profile()
 prof = prof.runctx("real_main()", globals(), locals())
 stream = StringIO.StringIO()
 stats = pstats.Stats(prof, stream=stream)
 stats.sort_stats("time")  # Or cumulative
 stats.print_stats(80)  # 80 = how many to print
 # The rest is optional.
 # stats.print_callees()
 # stats.print_callers()
 logging.info("Profile data:\n%s", stream.getvalue())

#main = profile_main
main = real_main
if __name__ == "__main__":
  main()
